import java.util.Arrays;

public class MyArrayList <E>{
    private Object[] elementData;//定义一个数组.没有分配内存
    private int usedSize;//定义数组的大小的变量
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENT={};//默认的一个空数组，标准的定义一个空的数组。
    public MyArrayList(){
        this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENT;//构造方法，赋初值为定义的空数组元素个数为0；不随意引用
    }
    //对链表进行大小的开辟赋初值。并根据数组进行判断数组容量
    public MyArrayList(int capacity){
        //对参数进行判断
        if(capacity>0){
            this.elementData=new Object[capacity];//已分配空间的大小
        }else if(capacity==0){
            this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENT;//默认为空
        }else {
            throw new IllegalArgumentException("初始化的值不能为负数");
        }
    }
    public void add(int index,E e){
        rangeCheckForAdd(index);
        ensureCapacityInternal(usedSize+1);
        copy(index,e);
        usedSize++;
    }

    private void rangeCheckForAdd(int index){
        if(index<0||index>size()){
            throw new IndexOutOfBoundsException("Index位置不合法，不能插入");
        }
    }
    public int size(){
        return this.usedSize;
    }
    private void copy(int index,E e){
        for(int i=usedSize-1;i>=index;i--){
            elementData[i+1]=elementData[i];
        }
        elementData[index]=e;
    }
//添加元素
   public  boolean add(E e){
        //确定一个真正的容量,预测扩容，把检查顺序表空和满放到了一起，
       ensureCapacityInternal(usedSize+1);
       elementData[usedSize]=e;
       usedSize++;
       return true;
   }
   private void ensureCapacityInternal(int minCapacity){  //为空或者为已分配的值
        //计算出需要的容量
       int capacity = calculateCapacity(elementData,minCapacity);
       //拿着计算出的容量，看满了就继续扩容，如果是空的就进行内存分配。
       ensureExplicitCapacity(capacity);

   }
   //判断初始内存是否为空，为空返回默认值为10，不为空则返回初始赋值
    private static int calculateCapacity(Object[] elementData, int minCapacity){
        //1.是否之前elementData分配过大小
        if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENT){
            return Math.max(10,minCapacity);//minCapacity==0
        }
        //2.分配过后，就返回+1后的值。
        return minCapacity;//开始分配的值
    }
    //确定是否需要扩容
   private void  ensureExplicitCapacity(int minCapacity){
        //进不去if语句，说明数组还没有满
        if(minCapacity-elementData.length>0){
            //进入if语句说明函数已经满了，进行扩容。
            grow(minCapacity);
        }
   }
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    //扩容
   private void grow(int minCapacity){
        int oldCapacity=elementData.length;
        int newCapacity=oldCapacity+(oldCapacity>>1);//每次扩容为1.5倍扩容。
        if(newCapacity-minCapacity<0){
            newCapacity=minCapacity;
        }
        //是否需要超大空间
        if(newCapacity-MAX_ARRAY_SIZE>0){
            newCapacity=hugCapacity(minCapacity);

        }
        //在新容量的数组中，把旧数组进行拷贝。
       elementData= Arrays.copyOf(elementData,newCapacity);
   }
   //将最大数组进行扩容为超大数组，增加8个位置。
    private static int hugCapacity(int minCapacity){
        if(minCapacity<0){
            throw new OutOfMemoryError();

        }
        return (minCapacity>MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }



    @Override
    public String toString() {
        return "MyArrayList{" +
                "elementData=" + Arrays.toString(elementData) +
                ", usedSize=" + usedSize +
                '}';
    }
}
